<template>
	<canvas class="com-poster"
	:style="{
		width: options.width + 'px',
		height: options.height + 'px',
		left: -options.width + 'px',
		top: -options.height + 'px'
	}"
	:canvas-id="canvasId"></canvas>
</template>

<script>
	export default {
		props: {
			canvasId: {
				type: String,
				default: 'comCanvasPoster'
			}
		},
		data () {
			return {
				options: {
					width: 300,
					height: 450,
					background: '#ffffff',
					radius: 0
				}
			}
		},
		methods: {
			start ({data, options, success, fail}) {
				this.options = Object.assign({}, this.options, options || {})
				this.$nextTick(function () {
					setTimeout(() => {
						const ctx = uni.createCanvasContext(this.canvasId, this)
						//设置画布背景
						ctx.fillStyle = this.options.background
						this.drawRect(ctx, 0, 0, this.options.width, this.options.height, this.options.radius)
						ctx.clip();
						const array = this.genarateArray(data)
						for ( let i = 0; i < array.length; i++ ) {
							this.drawShadow(ctx, array[i].shadowColor, array[i].shadowBlur, array[i].shadowOffsetX, array[i].shadowOffsetY)
							if ( array[i].type == 'text' ) {
								const width = array[i].width || (this.options.width - array[i].x)
								const size = array[i].size || 24
								const weight = array[i].weight || 'normal'
								const family = array[i].family || 'Arial'
								ctx.font = `${weight} ${size}px ${family}`;
								let len = array[i].text.length
								let lineWidth = 0
								let lines = ['']
								let line = 0
								for ( let j = 0; j < len; j++ ) {
									lineWidth += ctx.measureText(array[i].text[j]).width;
									if ( lineWidth <= width ) {
										lines[line] += array[i].text[j]
									} else {
										if ( (array[i].lines || 0) == (line + 1) ) {
											break;
										} else {
											lineWidth = 0
											line++
											lines.push(array[i].text[j])
										}
									}
								}
								lines.forEach((line, key) => {
									if ( line ) {
										if ( array[i].style == 'fill' ) {
											ctx.fillStyle = array[i].color
											ctx.fillText(line, array[i].x, (key * (size + (array[i].lineHeight || 0))) + array[i].y)
										} else {
											ctx.strokeStyle = array[i].color
											ctx.strokeText(line, array[i].x, (key * (size + (array[i].lineHeight || 0))) + array[i].y)
										}
									}
								})
							} else if ( array[i].type == 'rect' ) {
								if ( array[i].style == 'fill' ) {
									ctx.fillStyle = array[i].color
									this.drawRect(ctx, array[i].x, array[i].y, array[i].width, array[i].height, array[i].radius, 'fill')
								} else {
									ctx.strokeStyle = array[i].color
									this.drawRect(ctx, array[i].x, array[i].y, array[i].width, array[i].height, array[i].radius, 'stroke')
								}
							} else if ( array[i].type == 'image' ) {
								this.drawImage(ctx, array[i].src, array[i].x, array[i].y, array[i].width, array[i].height, array[i].radius)
							}
						}
						setTimeout(() => {
							ctx.draw(false, () => {
								uni.canvasToTempFilePath({
									x: 0,
									y: 0,
									width: this.options.width,
									height: this.options.height,
									destWidth: this.options.width,
									destHeight: this.options.height,
									canvasId: this.canvasId,
									success: function(res) {
									  // 在H5平台下，tempFilePath 为 base64
									  success ? success(res) : null
									},
									fail: (err) => {
										fail ? fail(err) : null
									}
								}, this)
							})
						}, 100)
					}, 100)
				})
			},
			drawShadow (ctx, shadowColor, shadowBlur, shadowOffsetX, shadowOffsetY) {
				ctx.shadowColor = shadowColor || ''; // 阴影颜色
				ctx.shadowBlur = shadowBlur || 0; // 模糊距离
				ctx.shadowOffsetX = shadowOffsetX || 0; // 水平方向偏移
				ctx.shadowOffsetY = shadowOffsetY || 0; // 垂直方向偏移
			},
			drawRect (ctx, x, y, w, h, r = 0, action = 'fill') {
				if (w < 2 * r) {
				    r = w / 2;
				}
				if (h < 2 * r) {
				    r = h / 2;
				}
				ctx.beginPath()
				ctx.moveTo(x + r, y);
				ctx.arcTo(x + w, y, x + w, y + h, r);
				ctx.arcTo(x + w, y + h, x, y + h, r);
				ctx.arcTo(x, y + h, x, y, r);
				ctx.arcTo(x, y, x + w, y, r);
				ctx[action]();
				ctx.closePath()
			},
			drawImage (ctx, img, x, y, w, h, r = 0) {
				if (w < 2 * r) {
				    r = w / 2;
				}
				if (h < 2 * r) {
				    r = h / 2;
				}
				ctx.save();
				ctx.beginPath()
				ctx.moveTo(x + r, y);
				ctx.arcTo(x + w, y, x + w, y + h, r);
				ctx.arcTo(x + w, y + h, x, y + h, r);
				ctx.arcTo(x, y + h, x, y, r);
				ctx.arcTo(x, y, x + w, y, r);
				ctx.fill()
				ctx.closePath()
				ctx.clip();
				ctx.drawImage(img, x, y, w, h);
				ctx.restore();
			},
			genarateArray (value) {
				const type = Object.prototype.toString.call(value)
				return value ? type == '[object Object]' ? [value] : value : null
			}
		}
	}
</script>

<style>
	.com-poster {
		position: fixed;
		opacity: 0;
		/* #ifndef APP-NVUE */
		z-index: -1;
		/* #endif */
	}
</style>